package es.uma.scgt.controlador;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import es.uma.scgt.dao.EquipoDao;
//import es.uma.scgt.dao.EquipoDaoImpl;
import es.uma.scgt.dao.ManejadorSession;
import es.uma.scgt.dao.RolDao;
import es.uma.scgt.dao.UsuarioDao;
import es.uma.scgt.mail.Correo;
import es.uma.scgt.modelo.Equipo;
import es.uma.scgt.modelo.Rol;
import es.uma.scgt.modelo.Usuario;

@Controller
public class UsuarioControlador {

	public static final String PAGINA_CRUD_USUARIO = "CrudUsuario";
	public static final String PARAM_EQUIPO_LIST = "equipoList";
	public static final String PARAM_ROL_LIST = "rolList";
	public static final String PARAM_USUARIO_LIST = "usuarioList";
	public static final String ERROR_ACCESO_DENEGADO_JSP = "ErrorAccesoDenegado";
	public static final String GESTION_USUARIO_JSP = "GestionUsuario";
	

	@Autowired
	private EquipoDao equipoDao;
	@Autowired
	private UsuarioDao usuarioDao;
	@Autowired
	private RolDao rolDao;

	@RequestMapping("/CrudUsuario")
	@Transactional
	public String iniCrudUsuario(ModelMap model) {
		model.addAttribute(PARAM_USUARIO_LIST, usuarioDao.getSoloActives());
		model.addAttribute(PARAM_ROL_LIST, rolDao.listaRol());
		model.addAttribute(PARAM_EQUIPO_LIST, equipoDao.getTodosEquipo());
		return PAGINA_CRUD_USUARIO;
	}
	
	
	
	@RequestMapping(value="/GuardarUsuario", method=RequestMethod.POST)
	@Transactional
	public String GuardarUsuario(ModelMap model, @RequestParam("usuarioId") Integer usuarioId, @RequestParam("nombre") String nombre, @RequestParam("apellido") String apellido, @RequestParam("apellido2") String apellido2, @RequestParam("email") String email, @RequestParam("rol") int rol, @RequestParam(value="equipo", required=false) Integer equipo, @RequestParam(value="confirmacion", required=false) Boolean confirmacion, @RequestParam(value="listaEquipos", required=false) String listaEquipos) {
		
		String contrasena;
		contrasena= apellido+UUID.randomUUID().toString().substring(0, 5);
		
		if(confirmacion == null){
			confirmacion = false;
		}
		
		if(confirmacion == true){
			//Enviar email de confirmacion
			//Constructor Correo
			Correo c = new Correo();
			
			List<String> emails = new ArrayList<String>();
			emails.add(email);
			
			String cuerpo, cabecera, subject, body;
			cabecera = "Registro nuevo Usuario: {0}";
			subject = MessageFormat.format(cabecera, usuarioId);
			
			cuerpo = "Ha sido dado de alta en SCGT. <br> Su nombre de usuario es: {0}. <br> Su contrasena provisional es: {1}. <br> <br> Por favor cambie su contrasena por una mas segura.";
			body = MessageFormat.format(cuerpo, email, contrasena);
			
			c.enviarCorreo(emails, subject, body);
			
		}
		if (usuarioId == null) {
			// usuario nuevo
			Usuario usuario = new Usuario();
			usuario.setActive(1);
			rellenarUsuario(usuarioId, nombre, apellido, apellido2, email, rol, listaEquipos, contrasena,usuario);
			usuarioDao.crearUsuarioNuevo(usuario);

			// TODO send email to the user's email, then It can access to the
			// system
			System.err.println("TODO send email to the " + usuario.getEmail() + "'s email, then It can access to the system");

		} else {
			Usuario tmpUsuario = usuarioDao.encuentraUsuarioPorId(usuarioId);
			rellenarUsuario(usuarioId, nombre, apellido, apellido2, email, rol, listaEquipos, null, tmpUsuario);
			usuarioDao.editarUsuario(tmpUsuario);
		}
		
		
		// TODO enviar email

		return "redirect:/CrudUsuario.html";//iniCrudUsuario(model);
	}

	@RequestMapping("/EliminarUsuario")
	@Transactional
	public @ResponseBody boolean EliminarUsuario(@RequestParam("usuarioId") Integer usuarioId) {

		usuarioDao.borrarUsuario(usuarioId);

		return true;

	}

	private void rellenarUsuario(Integer usuarioId, String nombre, String apellido, String apellido2, String email, int rol, String equiposString, String contrasena, Usuario usuario) {
		usuario.setId(usuarioId);
		usuario.setNombre(nombre);
		usuario.setApellido1(apellido);
		usuario.setApellido2(apellido2);
		usuario.setEmail(email);
		if(contrasena!=null){
			usuario.setPassword(contrasena);
		}
		usuario.setRol(rolDao.getRolPorId(rol));
		
		List<Equipo> origE = usuario.getEquipo();
		Set<Integer> seq = new HashSet<Integer>();
		if(origE != null){
			for (Equipo equipo : origE) {
				seq.add(equipo.getId());
			}
		}

		List<Equipo> equipos = new ArrayList<Equipo>();
		if(equiposString != null && equiposString.length() > 0){
			List<Equipo> todosEquipos = equipoDao.getTodosEquipo();
			for (Equipo item : todosEquipos) {
				if(!seq.contains(item.getId()) && equiposString.contains(item.getNombre())){
					Equipo equipo = equipoDao.getEquipoPorId(item.getId());
					if(equipo != null){
						if (equipo.getUsuarios() == null) {
							equipo.setUsuarios(new ArrayList<Usuario>());
						}
						equipo.getUsuarios().add(usuario);
						equipos.add(equipo);
					}
				}
			}
		}

		usuario.setEquipo(equipos);
	}

	// @RequestMapping("/BuscarUsuario")
	// @Transactional
	// // public String BuscarUsuario(ModelMap model, @RequestParam("busqueda")
	// String busqueda, @RequestParam(value="x", required=false) Integer x,
	// @RequestParam(value="y", required=false) Integer y){
	//
	//
	// model.addAttribute(PARAM_USUARIO_LIST,usuarioDao.SelectGeneral(busqueda));
	// model.addAttribute(PARAM_ROL_LIST, rolDao.listaRol());
	// model.addAttribute(PARAM_EQUIPO_LIST, equipoDao.getTodosEquipo());
	//
	// return PAGINA_CRUD_USUARIO;
	// }

	// ///////////////////////////////////////////////////////////////////////////////////////

	// @RequestMapping("/EditarUsuario")
	// public String editarUsuario(ModelMap model, @RequestParam("usuarioId")
	// int usuarioId) {
	// // Requisitos:
	// // * Seas Administrador
	// if (SoyAdmin()) {
	// // Devolvemos:
	// // * Un usuario que exista. El id debe ser pasado por argumento
	// // * La lista de equipos
	// // * La lista de roles
	// //
	// // Interfaz:
	// // * No se muestre contrase�a
	// // * Se muestre el boton Editar Usuario
	// model.addAttribute("editando", true);
	//
	// Usuario usuario = usuarioDao.encuentraUsuarioPorId(usuarioId);
	// model.addAttribute("usuario", usuario);
	// List<Equipo> equipos = equipoDao.listaEquipo();
	// model.addAttribute("equipos", equipos);
	//
	// List<Rol> roles = rolDao.listaRol();
	// model.addAttribute("roles", roles);
	//
	// return GESTION_USUARIO_JSP;
	// } else {
	//
	// return ERROR_ACCESO_DENEGADO_JSP;
	// }
	//
	// }
	//

}
